package io;

import basic.*;
import utils.ByteUtils;

import java.nio.ByteBuffer;
import java.util.*;

/**
 *  总体结构
 * |-----|--------|------|------|
 * |type |totalLen|  key | value|
 * |-----|--------|------|------|
 * RDB的结构：魔数、RDB版本、database(SELECTDB、db_num、key_value_pais)、EOF、check_num
 */
public class JdbWriter {

    public JdbWriter() {

    }

    public byte[] write(JodisObject jodisObject) {
        return new byte[0];
    }

    /**
     *  For JodisString
     * |-----|-----|------|------|
     * |kLen | key | vLen | value|
     * |-----|-----|------|------|
     * 写入字节流
     * @param key
     * @param value
     * @return
     */
    public ByteBuffer writeString(String key, JodisString value){
        String valueString = value.getHolder();
        byte[] keyBytes = ByteUtils.stringBytesWithLen(key);
        byte[] valueBytes = ByteUtils.stringBytesWithLen(valueString);
        int keyLen = keyBytes.length;
        int valueLen = valueBytes.length;

        int len = JdbConstant.JDB_TYPE_SIZE + JdbConstant.JDB_INT_SIZE + keyLen + valueLen;

        ByteBuffer buffer = ByteBuffer.allocate(len);
        buffer.put(JdbConstant.JDB_TYPE_STRING);
        buffer.putInt(len);
        //keyBytes中包含长度和键内容
        buffer.put(keyBytes);
        buffer.put(valueBytes);

        return buffer;
    }
    public static void main(String[] args){
        JdbWriter jdbWriter = new JdbWriter();
        String key = "hello";
        System.out.println(key);
    }
    /**
     *  For JodisList
     * |-----|-----|-------|-------|------|-------|
     * |kLen | key |listLen|itemLen| item |  ...  |
     * |-----|-----|-------|-------|------|-------|
     * @param key
     * @param value
     * @return
     */
    public ByteBuffer writeList(String key, JodisList value) {
        List<String> values = value.getHolder();
        return writeCollection(key,values,JdbConstant.JDB_TYPE_LIST);
    }

    /**
     *  For JodisHash
     * |-----|-----|-------|--------|-------|--------|-------|------|
     * |kLen | key |hashLen|filedLen| filed |valueLen| value | ...  |
     * |-----|-----|-------|--------|-------|--------|-------|------|
     * @param key
     * @param value
     * @return
     */
    public ByteBuffer writeHash(String key, JodisHash value) {
        Map<String, String> values = value.getHolder();
        List<String> kvs = new ArrayList<>(values.keySet());
        kvs.addAll(values.values());
        return writeCollection(key, kvs, JdbConstant.JDB_TYPE_HASH);
    }

    /**
     *  For JodisSet
     * |-----|-----|-------|-------|------|-------|
     * |kLen | key | setLen|itemLen| item |  ...  |
     * |-----|-----|-------|-------|------|-------|
     * @param key
     * @param value
     * @return
     */
    public ByteBuffer writeSet(String key, JodisSet value) {
        Set<String> values = value.getHolder();
        return writeCollection(key,values,JdbConstant.JDB_TYPE_SET);
    }



    private ByteBuffer writeCollection(String key, Collection<String> values, byte jdbType) {
        int totalLen = 0;
        List<byte[]> valueBytes = new ArrayList<>(values.size());
        for(String item : values){
            byte[] bytes = ByteUtils.stringBytesWithLen(item);
            totalLen += bytes.length;
            valueBytes.add(bytes);
        }

        byte[] keys = ByteUtils.stringBytesWithLen(key);
        int keyLen = keys.length;
        totalLen += keyLen;
        // 集合长度
        totalLen += JdbConstant.JDB_INT_SIZE;
        // 标志位长， 总长度
        totalLen += JdbConstant.JDB_TYPE_SIZE  + JdbConstant.JDB_INT_SIZE;

        ByteBuffer buffer = ByteBuffer.allocate(totalLen);
        buffer.put(jdbType);
        buffer.putInt(totalLen);
        buffer.put(keys);
        buffer.putInt(values.size());
        for(byte[] item : valueBytes){
            buffer.put(item);
        }

        return buffer;
    }
}
